package com.sec.android.app.myfiles.util;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.widget.Toast;

import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.activity.FileListActivity;
import com.sec.android.app.myfiles.dialog.ConfirmUnsupportedFileDialog;
import com.sec.android.app.myfiles.info.AppConstants;
import com.sec.android.app.myfiles.info.FileType;
import com.sec.android.app.myfiles.info.MediaFile;
import com.sec.android.app.myfiles.info.MimeType;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.local.file.LocalFileRecord;
import com.sec.android.app.myfiles.module.search.SearchFileRecord;
import com.sec.android.app.myfiles.navigation.NavigationInfo;
import com.sec.android.app.myfiles.navigation.NavigationManager;

import java.io.File;
import java.util.List;

/**
 * Created by admin on 2016-06-17.
 */
public class FileExecute {

    private static final String MERGE_PACKAGE = "com.samsung.android.app.capture3d.merged";
    private static final String SCULPTOR_PACKAGE = "com.samsung.android.app.capture3d.editor";
    private static final String SCULPTOR_ACTIVITY = ".MainActivity";
    private static final String TAG = "FileExecute";

    public static void openFile(int processId, FileRecord record, Activity activity) {
        Intent intent = new Intent();
        if (activity != null) {
            intent = getOpenFileIntent(processId, false, intent, record, activity);

            PackageManager pm = activity.getPackageManager();
            // "pm.queryIntentActivities(intent, 0).size() > 0" cannot guarantee that activities processing an intent exist.
            // So we have to process ActivityNotFoundException in case of using startActivityForResult() or startActivity().
            // We need to readjust under construction if a delay happens by calling queryIntentActivities().
            if (pm != null) {
                if (!pm.queryIntentActivities(intent, 0).isEmpty()) {
                    String mimeType = intent.getType();
                    int fileType = MediaFile.getFileTypeForMimeType(mimeType);

                    try {
                        if (FileType.isAudioFileType(fileType)) {
                            activity.startActivityForResult(intent, AppConstants.OPEN_FILE);
                        } else if (FileType.isInstallFileType(fileType) && UiUtils.isUPSM(activity.getApplicationContext())) {
                            onExecuteFailed(record, activity);
                        } else {
                            activity.startActivity(intent);
                        }
                        if (FileType.isUnusedFilesCategoryType(fileType)) {
                            Uri currentUri = intent.getData();
                            if (FileUtils.isMediaProviderUri(currentUri)) {
                                FileUtils.updateDateAccessed(activity, currentUri);
                            }
                        }
                        FileUtils.updateRecentFile(activity, record);
                    } catch (ActivityNotFoundException e) {
                        onExecuteFailed(record, activity);
                    } catch (NullPointerException e) {
                        Log.e(TAG, "NullPointerException:" + e.toString());
                    }
                } else {
                    onExecuteFailed(record, activity);
                    try {
                        Log.e(TAG, "There is no activity for this intent. type" + intent.getType() + "  scheme:" + intent.getData().getScheme());
                    } catch (NullPointerException e) {
                        Log.e(TAG, "Intent is null : " + e.getMessage());
                    }
                }
            } else {
                onExecuteFailed(record, activity);
            }
        }
    }

    private static void onExecuteFailed(FileRecord record, Activity activity) {
        boolean handled = false;
        int marketType = UiUtils.getSupportedMarketType(activity.getApplicationContext());
        String message = activity.getString(R.string.unable_to_find_application);
        if (record.isEncryptionFileType()) {
            message = activity.getString(R.string.file_lock);
            handled = true;
        } else if (UiUtils.isUPSM(activity)) {
            if (!record.isApkFileType()) {
                message = activity.getString(R.string.unable_to_open_file_add_app_to_upsm_and_try_again);
            }
            handled = true;
        } else if (record.getExt().isEmpty()) {
            handled = true;
        } else if (AppConstants.MarketType.NOT_SUPPORT == marketType) {
            handled = true;
        }

        if (handled) {
            Toast.makeText(activity, message, Toast.LENGTH_LONG).show();
        } else {
            showUnsupportedFileDialog(record, activity, marketType);
        }
    }

    private static void showUnsupportedFileDialog(FileRecord record, Activity activity, int marketType) {
        String downloadFrom = null;
        if (marketType == AppConstants.MarketType.GALAXY_APPS) {
            downloadFrom = activity.getApplicationContext().getResources().getString(R.string.galaxy_apps);
        }
        ConfirmUnsupportedFileDialog dialogFragment = ConfirmUnsupportedFileDialog.getInstance(record.getExt(), marketType, downloadFrom);
        if (dialogFragment != null) {
            dialogFragment.showAllowingStateLoss(activity.getFragmentManager(), "unsupported_file");
        }
    }

    private static Intent getOpenFileIntent(int processId, boolean bPickFilesMode, Intent intent, FileRecord record, Activity activity) {

        String path = record.getFullPath();
        MediaFile.MediaFileInfo info = MediaFile.getMediaFileInfo(path, activity);

        if (info != null) {
            int fileType = info.fileType;
            String mimeType = info.mimeType;

            if (fileType == FileType.UNKNOWN) {
                mimeType = "";
            }

            if (FileType.isDrmFileType(info.fileType)) {
                if (DrmUtils.isDRMFile(activity, path)) {
                    mimeType = DrmUtils.getRealMimeTypeOfDRM(activity, path);
                }
            }

            String absolutePath = null;
            if (path != null) {
                File file = SemFwWrapper.file(path);
                Uri uriFromFile = FileUtils.getContentUri(activity.getApplicationContext(), path);
                absolutePath = file.getAbsolutePath();

                if (FileType.isInstallFileType(fileType)) {
                    intent.setAction(android.content.Intent.ACTION_VIEW);
                    if (fileType == FileType.APK) {
                        intent.setDataAndType(uriFromFile, MimeType.APK);
                    } else if (fileType == FileType.WGT) {
                        intent.setDataAndType(uriFromFile, MimeType.WIDGET);
                    }
                    if (activity instanceof FileListActivity && ((FileListActivity) activity).isPinWindow()) {
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    }
                    List<ResolveInfo> resInfoList = activity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
                    for (ResolveInfo resolveInfo : resInfoList) {
                        String packageName = resolveInfo.activityInfo.packageName;
                        activity.grantUriPermission(packageName, uriFromFile, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    }
                } else if (FileType.isImageFileType(fileType)) {
                    intent.setAction(android.content.Intent.ACTION_VIEW);
                    Uri uri;
                    if (!bPickFilesMode)
                        uri = FileUtils.getUriByPath(activity, path);
                    else
                        uri = uriFromFile;
                    intent.setDataAndType(uri, mimeType);
                    intent.putExtra(Intent.EXTRA_STREAM, uri);
                } else if (FileType.is3DCaptureFileType(fileType)) {
                    Intent captureAppIntent = new Intent("android.intent.action.MAIN");
                    captureAppIntent.setComponent(new ComponentName(MERGE_PACKAGE, SCULPTOR_PACKAGE + SCULPTOR_ACTIVITY));
                    captureAppIntent.addCategory("android.intent.category.LAUNCHER");
                    captureAppIntent.putExtra("PATH", path);
                    return captureAppIntent;
                } else {
                    intent.setAction(android.content.Intent.ACTION_VIEW);
                    Uri uri = null;
                    Context context = activity.getApplicationContext();
                    if (context != null) {
                        uri = FileUtils.getUriByPath(context, path);
                    }
                    intent.setDataAndType(uri, mimeType);
                    intent.putExtra(AppConstants.INTENT_KEY_FILENAME, absolutePath);
                    intent.putExtra(Intent.EXTRA_STREAM, uri);

                    if (FileType.isVideoFileType(fileType)) {
                        setVideoIntent(processId, intent, record, activity);
                    }
                }
            }

            intent.putExtra(AppConstants.INTENT_FROM_MYFILES, true);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.putExtra(AppConstants.INTENT_KEY_FILE_PATH, absolutePath);
        }

        return intent;
    }

    public static void setVideoIntent(int processId, Intent intent, FileRecord record, Activity activity) {
        NavigationInfo info = NavigationManager.getInstance(processId).getCurInfo();
        if (info != null) {
            FileRecord parent = info.getCurRecord();
            if (parent != null) {
                if (parent instanceof LocalFileRecord || record.getStorageType() == FileRecord.StorageType.Recent) {
                    intent.putExtra("bucketId", getBucketId(record, activity));
                }

                if (parent instanceof SearchFileRecord) {
                    intent.putExtra("searchStr", parent.getName());
                }

                /**
                 * These values depend on Video
                 */
                final int TIME_ASC = 200;
                final int TIME_DESC = 210;
                final int TYPE_ASC = 220;
                final int TYPE_DESC = 230;
                final int NAME_ASC = 240;
                final int NAME_DESC = 250;
                final int SIZE_ASC = 260;
                final int SIZE_DESC = 270;

                int type = PreferenceUtils.getSortByType(activity, info);
                int order = PreferenceUtils.getSortByOrder(activity, info);

                int sortby = 0;
                if (order == AppConstants.SortByOrder.ASC) {
                    if (type == AppConstants.SortByType.TIME) {
                        sortby = TIME_ASC;
                    } else if (type == AppConstants.SortByType.TYPE) {
                        sortby = TYPE_ASC;
                    } else if (type == AppConstants.SortByType.NAME) {
                        sortby = NAME_ASC;
                    } else if (type == AppConstants.SortByType.SIZE) {
                        sortby = SIZE_ASC;
                    }
                } else {
                    if (type == AppConstants.SortByType.TIME) {
                        sortby = TIME_DESC;
                    } else if (type == AppConstants.SortByType.TYPE) {
                        sortby = TYPE_DESC;
                    } else if (type == AppConstants.SortByType.NAME) {
                        sortby = NAME_DESC;
                    } else if (type == AppConstants.SortByType.SIZE) {
                        sortby = SIZE_DESC;
                    }
                }
                intent.putExtra("sortBy", sortby);
                intent.putExtra("from-myfiles", true);
            }
        }
    }

    private static int getBucketId(FileRecord record, Activity activity) {
        int nRet = 0;
        ContentResolver cr = activity.getContentResolver();
        Uri uri = record.getUri(activity);
        if (uri != null && !uri.getAuthority().equals(FileUtils.FILE_PROVIDER_AUTHORITY)) {
            try (Cursor c = cr.query(uri, new String[]{
                    "bucket_id"}, null, null, null)) {
                if (c != null && c.getCount() > 0) {
                    if (c.moveToFirst()) {
                        nRet = c.getInt(0);
                    }
                }
            }
        }
        return nRet;
    }
}